SQLmap in action
测试自己的机器上的项目可以随便用,测试他人的服务或线上项目时避免使用(谨慎使用)os系列参数
准备阶段
- 找有漏洞的接口
- 使用AWVS等漏扫工具对项目进行扫描,找到问题的接口;
- 通过其他途径,找到可能存在SQL注入问题的接口;
- 安装SQLmap工具
- 从 SQLmap官网 获取(推荐开发同事使用该方式);
- 使用Kali系统(较重,仅推荐长期进行渗透测试的同事使用);
环境说明
key | value | remark |
---|---|---|
目标接口 | http://192.168.154.1:1993/sql?ok=1 | 通过/sql接口的ok参数,将payload传到数据库 |
数据库 | Postgres 13 |
测试示例
- 使用--url 指定接口url
- 当前目标接口没有登录验证,如果有登录验证,需要使用--cookie 传递cookie值
- 如果知道目标服务使用的是什么数据库,可以通过--dbms 指定只用这种数据库的payload
- 假设接口有多个参数(ok、no),但只有"ok"参数可以被利用,可以使用-p 参数指定利用参数
- 嫌麻烦可以试试--wizard参数,这个参数会引导用户进行测试,适合新手或忘了SQLmap怎么使用的用户,这里就不演示了。
假设当前环境可用cookie值为"xiaolongtest",已知"ok"参数可被利用,不知道后端数据库是什么类型,可以这样操作,获取后端数据库类型。
shell
sqlmap --cookie xiaolongtest --url "http://192.168.154.1:1993/sql?ok=1&no=2" -D DB -p ok
如果指定了错误(无法被利用)的参数,则不会有结果。
对于以发现问题为目的的开发人员到了这里,就可以了,因为即使是盲注,没能直接返回数据库的内容,但也是恶意用户传入的命令被执行了,不死心可以用--tables让sqlmap返回所有库表。
shell
sqlmap --cookie xiaolongtest --url "http://192.168.154.1:1993/sql?ok=1&no=2" --dbms=PostgreSQL --tables
库表信息被打印出来,就可以完全死心了,这个接口肯定需要修复。
当业务复杂,不确定哪个参数会被利用,就不要使用-p参数,url中的参数尽量写全,这样在测试过程中SQLmap会检测所有参数,只是执行过程中,SQLmap会要求交互,有交互时根据提示进行操作即可。
自助
不会使用时,可以执行--help或man命令,查看帮助信息
--help命令
shell
sqlmap --help
man命令
shell
man sqlmap
示例代码
目录结构
mermaid
graph LR
subgraph 目录结构
A[root]---B[src]
A---C[go.mod]
B---D[application.go]
end
application.go
go
package main
import (
"container/list"
"database/sql"
"log"
"github.com/gin-gonic/gin"
_ "github.com/lib/pq"
)
func main() {
connStr := "dbname=akmc user=sun password=1 host=127.0.0.1 port=5432 connect_timeout=5 sslmode=disable"
db, err := sql.Open("postgres", connStr)
if nil != err {
log.Panicln(err)
}
r := gin.Default()
r.GET("/sql", func(c *gin.Context) {
var okValue = "SELECT guid FROM ep WHERE guid = '" + c.Request.URL.Query().Get("ok") + "'"
log.Println(okValue)
rsInDb, err := db.Query(okValue)
if nil != err {
log.Println(err)
}
var resultList list.List
for rsInDb.Next() {
var value string
_ = rsInDb.Scan(&value)
var row = make(map[string]interface{})
row["guid"] = value
resultList.PushBack(row)
}
var result []interface{}
for e := resultList.Front(); e != nil; e = e.Next() {
// do something with e.Value
result = append(result, e.Value)
}
c.JSON(200, gin.H{
"message": result,
})
})
r.Run("0.0.0.0:1993")
}
go.mod
go
module sqlmap
go 1.16
require (
github.com/gin-gonic/gin v1.7.4 // indirect
github.com/go-playground/validator/v10 v10.9.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/lib/pq v1.10.3 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/ugorji/go v1.2.6 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)